package com.jzo2o.orders.manager.handler;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.constants.UserType;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.mapper.OrdersMapper;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.jzo2o.orders.manager.model.dto.OrderCancelDTO;
import com.jzo2o.orders.manager.service.IOrdersCreateService;
import com.jzo2o.orders.manager.service.IOrdersManagerService;
import com.jzo2o.orders.manager.service.IOrdersRefundService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * @author Mr.M
 * @version 1.0
 * @description 订单定时任务
 * @date 2023/12/15 10:14
 */
@Component
@Slf4j
public class OrdersHandler {

    @Resource
    private IOrdersCreateService ordersCreateService;

    @Resource
    private IOrdersManagerService ordersManagerService;

    @Resource
    private IOrdersRefundService ordersRefundService;

    @Resource
    private RefundRecordApi refundRecordApi;

    @Resource
    private OrdersMapper ordersMapper;

    /**
     * 自动取消支付超时的订单
     * 支付超时：从下单开始15分钟还没有支持
     */
    @XxlJob("cancelOverTimePayOrder")
    public void cancelOverTimePayOrder() {

        //查询出支付超时的订单
        List<Orders> ordersList = ordersCreateService.queryOverTimePayOrdersListByCount(100);
        if (CollUtils.isEmpty(ordersList)) {
            log.info("自动取消支付超时的订单，未查询到订单信息");
            return;
        }

        //遍历，调用订单取消方法
        for (Orders orders : ordersList) {
            OrderCancelDTO orderCancelDTO = BeanUtils.toBean(orders, OrderCancelDTO.class);
            //是系统本身来执行的操作，不是c端用户
            orderCancelDTO.setCurrentUserType(UserType.SYSTEM);
            orderCancelDTO.setCancelReason("订单超时支付，自动取消");
            ordersManagerService.cancel(orderCancelDTO);
        }

    }

    /**
     * 退款定时任务
     */
    @XxlJob("handleRefundOrders")
    public void handleRefundOrders() {

        //查询退款记录表
        List<OrdersRefund> ordersRefunds = ordersRefundService.queryRefundOrderListByCount(100);
        if (CollUtils.isEmpty(ordersRefunds)) {
            log.info("退款定时任务，未查询到订单的退款记录");
            return;
        }
        //遍历退款记录，请求支付服务进行退款
        for (OrdersRefund ordersRefund : ordersRefunds) {
            //请求支付服务进行退款
            requestRefundOrder(ordersRefund);
        }

        //如果退款成功更新订单的退款状态
    }

    /**
     * 请求退款
     *
     * @param ordersRefund 退款记录
     */
    public void requestRefundOrder(OrdersRefund ordersRefund) {
        ExecutionResultResDTO executionResultResDTO = null;
        //请求支付服务进行退款
        try {
            executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //解析退款结果，如果不是退款中 更新订单的退款状态
        if (ObjectUtils.isNotNull(executionResultResDTO) && executionResultResDTO.getRefundStatus() != OrderRefundStatusEnum.REFUNDING.getStatus()) {
            //更新订单的退款状态
            refundOrder(ordersRefund, executionResultResDTO);
        }

    }

    //更新订单的退款状态，只更新要么是退款成功要么是退款失败
    public void refundOrder(OrdersRefund ordersRefund, ExecutionResultResDTO executionResultResDTO) {

        //初始的退款状态为退款中
        Integer refundStatus = OrderRefundStatusEnum.REFUNDING.getStatus();
        //如果支付服务 返回退款成功
        if (executionResultResDTO.getRefundStatus() == OrderRefundStatusEnum.REFUND_SUCCESS.getStatus()) {
            refundStatus = OrderRefundStatusEnum.REFUND_SUCCESS.getStatus();
        } else if (executionResultResDTO.getRefundStatus() == OrderRefundStatusEnum.REFUND_FAIL.getStatus()) {//如果支付服务 返回退款失败
            refundStatus = OrderRefundStatusEnum.REFUND_FAIL.getStatus();
        }
        //如果是退款中状态，程序结束
        if (ObjectUtil.equal(refundStatus, OrderRefundStatusEnum.REFUNDING.getStatus())) {
            return;
        }
        //更新订单表的退款状态、支付服务的退款单号、第三方支付平台的退款单号
        //sql:update orders set refund_status=退款成功 where id=? and refund_status!=退款成功
        //sql:update orders set refund_status=退款失败 where id=? and refund_status!=退款失败

        LambdaUpdateWrapper<Orders> updateWrapper = new LambdaUpdateWrapper<Orders>()
                .eq(Orders::getId, ordersRefund.getId())//订单id
                .ne(Orders::getRefundStatus, refundStatus)//拼接  and refund_status!=退款成功  或 and refund_status!=退款失败
                .set(Orders::getRefundStatus, refundStatus)
                .set(Orders::getRefundId, executionResultResDTO.getRefundId())
                .set(Orders::getRefundNo, executionResultResDTO.getRefundNo());
        //更新订单表
        int update = ordersMapper.update(null, updateWrapper);
        if (update > 0) {
            //清除退款记录
            ordersRefundService.removeById(ordersRefund.getId());
        }

    }

    /**
     * 新启一个线程请求支付服务进行退款
     *
     * @param ordersRefundId 订单id
     */
    public void requestRefundNewThread(Long ordersRefundId) {
        //新启一个线程
        new Thread(() -> {
            //查询退款记录表
            OrdersRefund ordersRefund = ordersRefundService.getById(ordersRefundId);
            if (ObjectUtils.isNotNull(ordersRefund)) {
                //请求支付服务进行退款
                requestRefundOrder(ordersRefund);
            }
        }).start();
    }


}
